package com.bobo.cretrofit.interceptor;


import android.text.TextUtils;
import android.util.Log;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.Objects;

import okhttp3.Connection;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;

/**
 * okhttp的日志拦截器(日志太长，log打印不出来)，建议开发者自己实现
 * Created by liubo on 8/15/16.
 */
@Deprecated
public class LoggingInterceptor implements Interceptor {
    private static final String TAG = "LoggingInterceptor";

    @NotNull
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        long t1 = System.nanoTime();
        Response response = chain.proceed(request);
        long t2 = System.nanoTime();
        logForRequest(request, chain.connection());
        return logForResponse(response, t1, t2);
    }


    private Response logForResponse(Response response, long start, long end) {
        try {
            Log.i(TAG, "##===============================response Log=======================================##");
            Response.Builder builder = response.newBuilder();
            Response clone = builder.build();
            Log.i(TAG, "response: " + URLDecoder.decode(clone.request().url().toString()) + String.format("  in %.1fms", (end - start) / 1e6d));

            Headers headers = clone.headers();
            for (int i = 0; i < headers.size(); i++) {
                Log.i(TAG, headers.name(i) + ": " + headers.value(i));
            }
            Log.i(TAG, "code : " + clone.code());
            Log.i(TAG, "protocol : " + clone.protocol());
            if (!TextUtils.isEmpty(clone.message()))
                Log.i(TAG, "message : " + clone.message());

            ResponseBody body = clone.body();
            if (body != null) {
                MediaType mediaType = body.contentType();
                if (mediaType != null) {
                    Log.i(TAG, "responseBody's contentType : " + mediaType.toString());
                    if (isContentCanPrint(mediaType)) {
                        String resp = body.string();
                        Log.i(TAG, "responseBody's content : ");
                        body = ResponseBody.create(mediaType, resp);
                        return response.newBuilder().body(body).build();
                    } else {
                        Log.i(TAG, "responseBody's content : " + " maybe [file part] , too large too print , ignored!");
                    }
                }
            }
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
        return response;
    }


    private boolean isContentCanPrint(MediaType mediaType) {
        if (mediaType.type().equals("text")) {
            return true;
        }
        final String[] subTypeArrays = new String[]{"json", "xml", "html", "webviewhtml", "x-www-form-urlencoded"};
        return Arrays.asList(subTypeArrays).contains(mediaType.subtype());
    }


    private void logForRequest(Request request, Connection connection) {
        try {
            Log.i(TAG, "##===============================request Log=======================================##");
            Headers headers = request.headers();
            Log.i(TAG, "request: " + URLDecoder.decode(request.url().toString()) + "  on " + connection);
            Log.i(TAG, "method: " + request.method());
            for (int i = 0; i < headers.size(); i++) {
                Log.i(TAG, headers.name(i) + ": " + headers.value(i));
            }
            RequestBody requestBody = request.body();
            if (requestBody != null) {
                MediaType mediaType = requestBody.contentType();
                if (mediaType != null) {
                    Log.i(TAG, "requestBody's contentType : " + mediaType.toString());
                    if (isContentCanPrint(mediaType)) {
                        Log.i(TAG, "requestBody's content : ");
                        Log.i(TAG, bodyToString(request).replace("&", "\n"));
                    } else {
                        Log.i(TAG, "requestBody's content : " + " maybe [file part] , too large too print , ignored!");
                    }
                }
            }
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }

    private String bodyToString(final Request request) {
        try {
            final Request copy = request.newBuilder().build();
            final Buffer buffer = new Buffer();
            Objects.requireNonNull(copy.body()).writeTo(buffer);
            return URLDecoder.decode(buffer.readUtf8());
        } catch (final IOException e) {
            return "something error when show requestBody.";
        }
    }
}
